XIncludeFile "StructuresAndConstants.pbi"

Procedure.i AddControl(List Controls.Control(), pParentNode.i, pGadgetType.i, pGadgetName.s, pGadgetText.s, pSizing.i)
  AddElement(Controls())
  
  Controls()\Node = ListSize(Controls())
  Controls()\ParentNode = pParentNode
  Controls()\Type = pGadgetType
  Controls()\Name = pGadgetName
  Controls()\Text = pGadgetText
  Controls()\Sizing = pSizing
  
  ProcedureReturn Controls()\Node 
EndProcedure

Procedure FillControls(List Controls.Control(), *pCurrentNode, pParentNode = -1)

  If XMLNodeType(*pCurrentNode) <> #PB_XML_Normal
    ProcedureReturn 
  EndIf
  
  Protected NodeName.s = GetXMLNodeName(*pCurrentNode)
  NewMap Attribute.s()

  If ExamineXMLAttributes(*pCurrentNode)
    While NextXMLAttribute(*pCurrentNode)
      Attribute(XMLAttributeName(*pCurrentNode)) = XMLAttributeValue(*pCurrentNode)
    Wend
  EndIf

  CurrentNode = AddControl(Controls(), ParentNode, Val(Attribute("GadgetType")), Attribute("Name"), Attribute("Text"), Val(Attribute("Sizing")))
  

  ; Now get the first child node (if any)
  ;    
  *ChildNode = ChildXMLNode(*pCurrentNode)
  
  ; Loop through all available child nodes and call this procedure again
  ;
  While *ChildNode <> 0
    FillControls(Controls(), *ChildNode, CurrentNode)
    *ChildNode = NextXMLNode(*ChildNode)
  Wend        

EndProcedure

Procedure OrientGadgets(Orientation.b, List g.GadgetLayout(), *AreaWidth.Word, *AreaHeight.Word, BorderTop.b = 0, BorderBottom.b = 0, BorderLeft.b = 0, BorderRight.b = 0, Spacing.b = 6)
  Protected MaxHeight.w = 0
  Protected MaxWidth.w = 0

  If Orientation = #Orientation_Horizontal
    ForEach g()
      MaxWidth = MaxWidth + g()\MinWidth + Spacing
      If MaxHeight < g()\MinHeight
        MaxHeight = g()\MinHeight
      EndIf
    Next

    MaxWidth = MaxWidth - Spacing + BorderLeft + BorderRight
    MaxHeight = MaxHeight + BorderTop + BorderBottom
  Else
    ForEach g()
      MaxHeight = MaxHeight + g()\MinHeight + Spacing
      If MaxWidth < g()\MinWidth
        MaxWidth = g()\MinWidth
      EndIf
    Next

    MaxWidth = MaxWidth + BorderLeft + BorderRight
    MaxHeight = MaxHeight - Spacing + BorderTop + BorderBottom
  EndIf

;-------------------------------------------------

  If *AreaWidth\w < MaxWidth
    *AreaWidth\w = MaxWidth
  EndIf
  If *AreaHeight\w < MaxHeight
    *AreaHeight\w = MaxHeight
  EndIf

;-------------------------------------------------
  
  Protected RemainingWidth.w, RemainingHeight.w
  
  If *AreaWidth\w > MaxWidth Or *AreaHeight\w > MaxHeight
    Protected WidthFlexCount.w = 0
    Protected HeightFlexCount.w = 0

    ForEach g()
      Select g()\FlexWidthType
        Case #Sizing_Stretch, #Sizing_Centre
          WidthFlexCount = WidthFlexCount + 1
      EndSelect
    
      Select g()\FlexHeightType
        Case #Sizing_Stretch, #Sizing_Centre
          HeightFlexCount = HeightFlexCount + 1
      EndSelect
    Next

    If Orientation = #Orientation_Horizontal
      RemainingWidth = Int((*AreaWidth\w - MaxWidth) / WidthFlexCount)
      RemainingHeight = *AreaHeight\w
    Else
      RemainingWidth = *AreaWidth\w
      RemainingHeight = Int((*AreaHeight\w - MaxHeight) / HeightFlexCount)
    EndIf

  EndIf

;-------------------------------------------------

  MaxHeight = 0 + BorderTop
  MaxWidth = 0 + BorderLeft

  ForEach g()
    g()\ActualX = MaxWidth
    g()\ActualY = MaxHeight
    
    Select g()\FlexWidthType
      Case #Sizing_Stretch
        If Orientation = #Orientation_Horizontal
          g()\ActualWidth = g()\MinWidth + RemainingWidth
        Else
          g()\ActualWidth = *AreaWidth\w - BorderLeft -  BorderRight
        EndIf
      Case #Sizing_Centre
        If Orientation = #Orientation_Horizontal
          t = Int(((g()\MinWidth + RemainingWidth) / 2) - (g()\MinWidth / 2))
          g()\ActualX = MaxWidth + t
          g()\ActualWidth = g()\MinWidth
          MaxWidth = MaxWidth - g()\MinWidth + ((g()\MinWidth + RemainingWidth) / 2) + t
        Else
          t = Int((*AreaWidth\w / 2) - (g()\MinWidth / 2))
          g()\ActualX = MaxWidth + t
          g()\ActualWidth = g()\MinWidth
        EndIf
      Default
        g()\ActualWidth = g()\MinWidth
    EndSelect
  
    Select g()\FlexHeightType
      Case #Sizing_Stretch
        If Orientation = #Orientation_Horizontal
          g()\ActualHeight = *AreaHeight\w - BorderTop - BorderBottom
        Else
          g()\ActualHeight = g()\MinHeight + RemainingHeight
        EndIf
      Case #Sizing_Centre
        If Orientation = #Orientation_Horizontal
          ;g()\ActualHeight = *AreaHeight\w - BorderTop - BorderBottom

          t = Int((*AreaHeight\w / 2) - (g()\MinHeight / 2))
          g()\ActualY = MaxHeight + t
          g()\ActualHeight = g()\MinHeight

        Else
          t = Int(((g()\MinHeight + RemainingHeight) / 2) - (g()\MinHeight / 2))
          g()\ActualY = MaxHeight + t
          g()\ActualHeight = g()\MinHeight
          MaxHeight = MaxHeight - g()\MinHeight + ((g()\MinHeight + RemainingHeight) / 2) + t
        EndIf
      Default
        g()\ActualHeight = g()\MinHeight
    EndSelect
  
    If Orientation = #Orientation_Horizontal
      MaxWidth = MaxWidth + Spacing + g()\ActualWidth
    Else
      MaxHeight = MaxHeight + Spacing + g()\ActualHeight
    EndIf
  Next

  ForEach g()
    ResizeGadget(g()\ID, g()\ActualX, g()\ActualY, g()\ActualWidth, g()\ActualHeight)
  Next
EndProcedure
; IDE Options = PureBasic 4.60 Beta 3 (Windows - x86)
; Folding = -
; EnableXP